package com.example.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.example.Filter.JwtAuthenticationTokenFilter;
/**
 * Security配置类用于在Spring Security中加密用户密码
 */

@Configuration
@EnableWebSecurity
public class SecurityConfig {


    /**
     * 可以在注册的时候调用这个方法对密码进行加密，然后再将加密之后的密码插入数据库，
     * 后面当用户登录时传递密码调用这个PasswordEncoder.matches("前端登录的密码","数据库查询的密码")
     * 如果匹配那么就可以登录成功。
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        //PasswordEncoder是Spring Security中用于加密和解密密码的接口
        // 使用 BCrypt 算法加密密码
        return new BCryptPasswordEncoder();
    }

    /**
     * 定义SpringSecurity过滤链来实现自定义的登录页。
     * @param http
     * @return
     * @throws Exception
     */
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf.disable()) // 仅在开发环境中禁用CSRF保护，生产环境中应启用
                .authorizeHttpRequests(authorizeRequests ->
                                authorizeRequests
                                        .requestMatchers("/register", "/login", "/test").permitAll() // 允许未认证用户访问注册和登录接口
                                        .anyRequest().authenticated()
                        // 其他所有请求都需要在请求头携带token进行认证
                )
                .logout(logout ->
                        logout
                                .permitAll() // 允许所有人访问注销端点
                )
                .sessionManagement(sessionManagement ->
                        sessionManagement
                                .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态会话，适用于REST API
                );
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }
}